﻿Imports System.IO

Public Class adminForm

    Private WithEvents UserClient As New TyranntOnlineUserService.TyranntUserServiceClient
    Private WithEvents CharClient As New TyranntOnlineCharacterService.TyranntCharacterServiceClient
    Private _token As String = ""
    Private _adminUsername As String = ""
    Private _deleteMe As Boolean = False

    Private _currentRace As New TyranntEngine.CharacterRace
    Private _currentPortrait As Integer = 1

    Private _currentSkill As New TyranntEngine.CharacterSkill
    Private _currentItem As New TyranntEngine.InventoryItem
    Private _currentClass As New TyranntEngine.CharacterClass
    Private _currentGuild As New TyranntEngine.CharacterGuild
    Private _itemTypeHashTable As New Hashtable
    Private _itemTypeValueHashTable As New Hashtable
    Private _itemsTable As New Hashtable
    Private _itemsValueTable As New Hashtable
    Private _skillTable As New Hashtable
    Private _skillValueTable As New Hashtable
    Private _classTable As New Hashtable
    Private _classValueTable As New Hashtable

    Private _loadingItems As Boolean = False
    Private _loadingItemTypes As Boolean = False
    Private _loadingSkills As Boolean = False
    Private _loadingUsers As Boolean = False
    Private _loadingRaces As Boolean = False
    Private _loadingClasses As Boolean = False
    Private _loadingGuilds As Boolean = False

    Public WriteOnly Property TokenString() As String
        Set(ByVal value As String)
            _token = value
        End Set
    End Property

    Public WriteOnly Property AdminUsername() As String
        Set(ByVal value As String)
            _adminUsername = value
        End Set
    End Property

    Private Sub adminForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        GetUsers()
        ScanImages()
    End Sub

    Public Sub ScanImages()
        Dim dirname As String = "./media"
        Dim dir As DirectoryInfo = New DirectoryInfo(dirname)

        Dim img As Image
        For Each imgFile In dir.GetFiles("*")
            img = Image.FromFile(dirname + "\" + imgFile.Name)
            If img.Width = 322 And img.Height = 358 Then
                raceImagesComboBox.Items.Add(imgFile.Name)
            ElseIf img.Width = 82 And img.Height = 95 Then
                racePortraitsComboBox.Items.Add(imgFile.Name)
            ElseIf img.Width = 50 And img.Height = 50 Then
                itemIconComboBox.Items.Add(imgFile.Name)
            ElseIf img.Width = 150 And img.Height = 250 Then
                itemImageComboBox.Items.Add(imgFile.Name)
            End If
        Next
    End Sub

    Private Sub mainTabControl_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mainTabControl.SelectedIndexChanged
        If mainTabControl.SelectedTab.Text = "Character Builder" Then
            LoadRaces()
            LoadSkills()
            LoadItems()
            LoadItemTypes()
            LoadClasses()
            LoadGuilds()
        End If
    End Sub

#Region "Users Section"
    Private Sub GetUsers()
        If _loadingUsers = False Then
            statusToolStripLabel.Text = "Fetching All Users"
            usersListView.Items.Clear()
            UserClient.GetUsersAsync(_token)
            _loadingUsers = True
        End If

    End Sub

    Private Sub UserClient_ChangeUserGroupCompleted(ByVal sender As Object, ByVal e As TyranntOnlineUserService.ChangeUserGroupCompletedEventArgs) Handles UserClient.ChangeUserGroupCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Change User Group - Error From Server [DEBUG]", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
        GetUsers()
    End Sub

    Private Sub UserClient_GetUsersCompleted(ByVal sender As Object, ByVal e As TyranntOnlineUserService.GetUsersCompletedEventArgs) Handles UserClient.GetUsersCompleted
        Dim sr As New StringReader(e.Result)
        Dim usersXML As XElement = XElement.Load(sr)
        Dim users = usersXML...<user>
        For Each aUser In users
            Dim item As New ListViewItem
            item.Text = aUser.@id
            item.SubItems.Add(aUser.<name>.Value)
            item.SubItems.Add(aUser.<alias>.Value)
            Dim userGroup As Integer = CInt(aUser.<group>.Value)
            If userGroup = 1 Then
                item.SubItems.Add("Admin")
            Else
                item.SubItems.Add("User")
            End If
            item.SubItems.Add(aUser.<email>.Value)
            usersListView.Items.Add(item)
        Next
        statusToolStripLabel.Text = ""
        usersListView.Enabled = True
        _loadingUsers = False
    End Sub

    Private Sub usersContextMenuStrip_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles usersContextMenuStrip.Opening
        If usersListView.SelectedItems.Count > 0 Then
            deleteUserContextMenuItem.Text = "Delete " + usersListView.SelectedItems(0).SubItems(1).Text
            Dim item As ListViewItem = usersListView.SelectedItems(0)
            If item.SubItems(3).Text.ToLower = "admin" Then
                If item.SubItems(1).Text.ToLower = "admin" Then
                    deleteUserContextMenuItem.Visible = False
                    UserToolStripMenuItem.Visible = False
                    AdministratorToolStripMenuItem.Visible = False
                    NewPasswordToolStripMenuItem.Visible = True
                    UserGroupToolStripMenuItem.Visible = False
                Else
                    UserToolStripMenuItem.Visible = True
                    deleteUserContextMenuItem.Visible = True
                    NewPasswordToolStripMenuItem.Visible = True
                    UserGroupToolStripMenuItem.Visible = True
                End If
                AdministratorToolStripMenuItem.Visible = False
            Else
                AdministratorToolStripMenuItem.Visible = True
                UserToolStripMenuItem.Visible = False
                deleteUserContextMenuItem.Visible = True
            End If
        Else
            e.Cancel = True
        End If
    End Sub

    Private Sub deleteUserContextMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles deleteUserContextMenuItem.Click
        Dim item As ListViewItem = usersListView.SelectedItems(0)

        ' Get the user ID from the selected list view item
        Dim userID As Integer
        If Integer.TryParse(item.Text, userID) = False Then
            MessageBox.Show("User ID of [" + item.Text + "] is not a valid number", "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        ' Now get the username
        Dim username As String = item.SubItems(1).Text

        ' Now confirm that the user is to be deleted.
        If MessageBox.Show("Are you sure you want to delete user " + username + "?", "Delete User " + userID.ToString + " Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
            ' we do so lets check that the user isnt deleting themselves
            If _adminUsername = username Then
                If MessageBox.Show("Are your really sure, You will be deleting yourself?", "Delete Own User / Loggof Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.No Then
                    Exit Sub
                End If
                _deleteMe = True
            End If
            usersListView.Enabled = False
            UserClient.RemoveUserAsync(_token, userID)
        End If

    End Sub

    Private Sub NewPasswordToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewPasswordToolStripMenuItem.Click
        Dim item As ListViewItem = usersListView.SelectedItems(0)

        ' Get the user ID from the selected list view item
        Dim userID As Integer
        If Integer.TryParse(item.Text, userID) = False Then
            MessageBox.Show("User ID of [" + item.Text + "] is not a valid number", "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If

        Dim np As New NewPasswordForm
        np.Token = _token
        np.UserID = userID
        np.ShowDialog()
    End Sub

    Private Sub AdministratorToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AdministratorToolStripMenuItem.Click
        ChangeUserGroup(1)
    End Sub

    Private Sub UserToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserToolStripMenuItem.Click
        ChangeUserGroup(2)
    End Sub

    Private Sub ChangeUserGroup(ByVal userGroup As Integer)
        Dim item As ListViewItem = usersListView.SelectedItems(0)

        ' Get the user ID from the selected list view item
        Dim userID As Integer
        If Integer.TryParse(item.Text, userID) = False Then
            MessageBox.Show("User ID of [" + item.Text + "] is not a valid number", "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        usersListView.Enabled = False
        UserClient.ChangeUserGroupAsync(_token, userID, userGroup)
    End Sub

    Private Sub UserClient_RemoveUserCompleted(ByVal sender As Object, ByVal e As TyranntOnlineUserService.RemoveUserCompletedEventArgs) Handles UserClient.RemoveUserCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "RemoveUser - Error From Server [DEBUG]", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
        If _deleteMe = True Then
            Me.Close()
        End If
        GetUsers()
    End Sub
#End Region

#Region "Race Code"

    Private Sub unknownRaceImageRadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles unknownRaceImageRadioButton.CheckedChanged
        DisplayRaceImage(_currentRace.UnknownSexImage)
    End Sub

    Private Sub femaleRaceImageComboBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles femaleRaceImageComboBox.CheckedChanged
        DisplayRaceImage(_currentRace.FemaleImage)
    End Sub

    Private Sub maleRaceImageComboBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles maleRaceImageComboBox.CheckedChanged
        DisplayRaceImage(_currentRace.MaleImage)
    End Sub

    Private Sub raceImagesComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceImagesComboBox.SelectedIndexChanged
        DisplayRaceImage(raceImagesComboBox.Text)
        If unknownRaceImageRadioButton.Checked = True Then
            _currentRace.UnknownSexImage = raceImagesComboBox.Text
        ElseIf maleRaceImageComboBox.Checked = True Then
            _currentRace.MaleImage = raceImagesComboBox.Text
        Else
            _currentRace.FemaleImage = raceImagesComboBox.Text
        End If
    End Sub

    Private Sub DisplayRaceImage(ByVal imageName As String)
        If imageName = "" Then
            raceImagePictureBox.Image = Nothing
        Else
            raceImagePictureBox.Load("./media/" + imageName)
        End If
    End Sub

    Private Sub racePortrait1PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortrait1PictureBox.Click
        _currentPortrait = 1
        RefreshRaceDetails()
    End Sub

    Private Sub racePortrait2PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortrait2PictureBox.Click
        _currentPortrait = 2
        RefreshRaceDetails()
    End Sub

    Private Sub racePortrait3PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortrait3PictureBox.Click
        _currentPortrait = 3
        RefreshRaceDetails()
    End Sub

    Private Sub racePortrait4PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortrait4PictureBox.Click
        _currentPortrait = 4
        RefreshRaceDetails()
    End Sub

    Private Sub racePortrait5PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortrait5PictureBox.Click
        _currentPortrait = 5
        RefreshRaceDetails()
    End Sub

    Private Sub racePortrait6PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortrait6PictureBox.Click
        _currentPortrait = 6
        RefreshRaceDetails()
    End Sub

    Private Sub RefreshRaceDetails()
        CheckValidRace()

        Dim pic1, pic2, pic3, pic4, pic5, pic6 As String
        If racePortraitMailRadioButton.Checked = True Then
            pic1 = _currentRace.MalePortrait(0)
            pic2 = _currentRace.MalePortrait(1)
            pic3 = _currentRace.MalePortrait(2)
            pic4 = _currentRace.MalePortrait(3)
            pic5 = _currentRace.MalePortrait(4)
            pic6 = _currentRace.MalePortrait(5)
        Else
            pic1 = _currentRace.FemalePortrait(0)
            pic2 = _currentRace.FemalePortrait(1)
            pic3 = _currentRace.FemalePortrait(2)
            pic4 = _currentRace.FemalePortrait(3)
            pic5 = _currentRace.FemalePortrait(4)
            pic6 = _currentRace.FemalePortrait(5)
        End If
        If pic1 = "" Then
            racePortrait1PictureBox.Image = Nothing
        Else
            racePortrait1PictureBox.Image = Image.FromFile(".\media\" + pic1)
        End If
        If _currentPortrait = 1 Then
            racePortrait1PictureBox.BorderStyle = BorderStyle.Fixed3D
        Else
            racePortrait1PictureBox.BorderStyle = BorderStyle.FixedSingle
        End If
        If pic2 = "" Then
            racePortrait2PictureBox.Image = Nothing
        Else
            racePortrait2PictureBox.Image = Image.FromFile(".\media\" + pic2)
        End If
        If _currentPortrait = 2 Then
            racePortrait2PictureBox.BorderStyle = BorderStyle.Fixed3D
        Else
            racePortrait2PictureBox.BorderStyle = BorderStyle.FixedSingle
        End If
        If pic3 = "" Then
            racePortrait3PictureBox.Image = Nothing
        Else
            racePortrait3PictureBox.Image = Image.FromFile(".\media\" + pic3)
        End If
        If _currentPortrait = 3 Then
            racePortrait3PictureBox.BorderStyle = BorderStyle.Fixed3D
        Else
            racePortrait3PictureBox.BorderStyle = BorderStyle.FixedSingle
        End If
        If pic4 = "" Then
            racePortrait4PictureBox.Image = Nothing
        Else
            racePortrait4PictureBox.Image = Image.FromFile(".\media\" + pic4)
        End If
        If _currentPortrait = 4 Then
            racePortrait4PictureBox.BorderStyle = BorderStyle.Fixed3D
        Else
            racePortrait4PictureBox.BorderStyle = BorderStyle.FixedSingle
        End If
        If pic5 = "" Then
            racePortrait5PictureBox.Image = Nothing
        Else
            racePortrait5PictureBox.Image = Image.FromFile(".\media\" + pic5)
        End If
        If _currentPortrait = 5 Then
            racePortrait5PictureBox.BorderStyle = BorderStyle.Fixed3D
        Else
            racePortrait5PictureBox.BorderStyle = BorderStyle.FixedSingle
        End If
        If pic6 = "" Then
            racePortrait6PictureBox.Image = Nothing
        Else
            racePortrait6PictureBox.Image = Image.FromFile(".\media\" + pic6)
        End If
        If _currentPortrait = 6 Then
            racePortrait6PictureBox.BorderStyle = BorderStyle.Fixed3D
        Else
            racePortrait6PictureBox.BorderStyle = BorderStyle.FixedSingle
        End If
        raceNameTextBox.Text = _currentRace.Name
        raceDescriptionTextBox.Text = _currentRace.Description
        raceStrModNumberBox.Value = _currentRace.StrengthModifier
        raceDexModNumBox.Value = _currentRace.DexterityModifier
        raceIntModNumBox.Value = _currentRace.IntelligenceModifier
        Dim raceSexImage As String = ""
        If unknownRaceImageRadioButton.Checked = True Then
            raceSexImage = _currentRace.UnknownSexImage
        ElseIf maleRaceImageComboBox.Checked = True Then
            raceSexImage = _currentRace.MaleImage
        Else
            raceSexImage = _currentRace.FemaleImage
        End If
        DisplayRaceImage(raceSexImage)
    End Sub

    Private Sub racePortraitMailRadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortraitMailRadioButton.CheckedChanged
        _currentPortrait = 1
        RefreshRaceDetails()
    End Sub

    Private Sub racePortraitFemailRadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortraitFemailRadioButton.CheckedChanged
        _currentPortrait = 1
        RefreshRaceDetails()
    End Sub

    Private Sub racePortraitsComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racePortraitsComboBox.SelectedIndexChanged
        If racePortraitMailRadioButton.Checked = True Then
            _currentRace.MalePortrait(_currentPortrait - 1) = racePortraitsComboBox.Text
        Else
            _currentRace.FemalePortrait(_currentPortrait - 1) = racePortraitsComboBox.Text
        End If
        RefreshRaceDetails()
    End Sub

    Private Sub raceNameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceNameTextBox.TextChanged
        _currentRace.Name = raceNameTextBox.Text
        CheckValidRace()
    End Sub

    Private Sub raceDescriptionTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceDescriptionTextBox.TextChanged
        _currentRace.Description = raceDescriptionTextBox.Text
        CheckValidRace()
    End Sub

    Private Sub raceStrModNumberBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceStrModNumberBox.ValueChanged
        _currentRace.StrengthModifier = CInt(raceStrModNumberBox.Value)
        CheckValidRace()
    End Sub

    Private Sub raceDexModNumBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceDexModNumBox.ValueChanged
        _currentRace.DexterityModifier = CInt(raceDexModNumBox.Value)
        CheckValidRace()
    End Sub

    Private Sub raceIntModNumBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceIntModNumBox.ValueChanged
        _currentRace.IntelligenceModifier = CInt(raceIntModNumBox.Value)
        CheckValidRace()
    End Sub

    Private Sub newRaceButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles newRaceButton.Click
        raceDetailsGroupBox.Enabled = False
        statusToolStripLabel.Text = "Adding Race"
        CharClient.AddRaceAsync(_token, _currentRace.ToXElement.ToString)
    End Sub

    Private Sub CharClient_AddRaceCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.AddRaceCompletedEventArgs) Handles CharClient.AddRaceCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Add Race Failed")
        End If
        newRaceButton.Enabled = True
        statusToolStripLabel.Text = ""
        LoadRaces()
    End Sub

    Private Sub racesListView_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles racesListView.SelectedIndexChanged
        If racesListView.SelectedItems.Count > 0 Then
            Dim item As ListViewItem = racesListView.SelectedItems(0)
            Dim raceID As Integer
            If Integer.TryParse(item.Text, raceID) = False Then
                MessageBox.Show("Race ID " + item.Text + " Is not a valid number", "Error Getting Race", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If
            raceDetailsGroupBox.Enabled = False
            statusToolStripLabel.Text = "Getting Race " + item.SubItems(0).Text + " ..."
            CharClient.GetRaceAsync(_token, raceID)
        End If
    End Sub

    Private Sub LoadRaces()
        If _loadingRaces = False Then
            statusToolStripLabel.Text = "Getting Races"
            raceDetailsGroupBox.Enabled = False
            racesListView.Enabled = False
            CharClient.GetRacesAsync(_token)
            _loadingRaces = True
        End If
    End Sub

    Private Sub CharClient_GetRaceCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetRaceCompletedEventArgs) Handles CharClient.GetRaceCompleted
        statusToolStripLabel.Text = ""
        raceDetailsGroupBox.Enabled = True
        If e.Result.Contains("[#]") = True Then
            MessageBox.Show(e.Result, "Failed to get Race", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        _currentRace.LoadXML(e.Result)
        RefreshRaceDetails()
        _loadingRaces = False
    End Sub

    Private Sub CharClient_GetRacesCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetRacesCompletedEventArgs) Handles CharClient.GetRacesCompleted
        racesListView.Items.Clear()
        Dim sr As New StringReader(e.Result)
        Dim racesXML As XElement = XElement.Load(sr)
        Dim races = racesXML...<race>
        For Each aRace In races
            Dim item As New ListViewItem
            item.Text = aRace.@id
            item.SubItems.Add(aRace.<name>.Value)
            racesListView.Items.Add(item)
        Next
        statusToolStripLabel.Text = ""
        racesListView.Enabled = True
        raceDetailsGroupBox.Enabled = True
        CheckValidRace()
    End Sub

    Private Sub CheckValidRace()
        If _currentRace.IsValid = True Then
            newRaceButton.Enabled = True
            If _currentRace.RaceID <> -1 Then
                raceUpdateButton.Enabled = True
            Else
                raceUpdateButton.Enabled = False
            End If
        Else
            newRaceButton.Enabled = False
            raceUpdateButton.Enabled = False
        End If
    End Sub

    Private Sub raceUpdateButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceUpdateButton.Click
        raceDetailsGroupBox.Enabled = False
        statusToolStripLabel.Text = "Updating Race"
        CharClient.UpdateRaceAsync(_token, _currentRace.ToXElement.ToString)
    End Sub

    Private Sub CharClient_UpdateRaceCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.UpdateRaceCompletedEventArgs) Handles CharClient.UpdateRaceCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Add Race Failed")
        End If
        newRaceButton.Enabled = True
        statusToolStripLabel.Text = ""
        LoadRaces()
    End Sub

    Private Sub raceClearButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceClearButton.Click
        _currentRace = New TyranntEngine.CharacterRace
        RefreshRaceDetails()
    End Sub

    Private Sub DeleteRaceToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteRaceToolStripMenuItem.Click
        Dim id As String = racesListView.SelectedItems(0).Text
        Dim raceID As Integer
        If Integer.TryParse(id, raceID) = False Then
            MessageBox.Show("Race ID " + id + " is invalid", "Failed to delete Race", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        racesListView.Enabled = False
        raceDetailsGroupBox.Enabled = False
        CharClient.DeleteRaceAsync(_token, raceID)
    End Sub

    Private Sub CharClient_DeleteRaceCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.DeleteRaceCompletedEventArgs) Handles CharClient.DeleteRaceCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Delete Race Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
        racesListView.Enabled = True
        raceDetailsGroupBox.Enabled = True
        LoadRaces()
    End Sub

    Private Sub racesContextMenuStrip_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles racesContextMenuStrip.Opening
        If racesListView.SelectedItems.Count = 0 Then
            e.Cancel = True
        Else
            DeleteRaceToolStripMenuItem.Text = "Delete " + racesListView.SelectedItems(0).SubItems(1).Text
        End If
    End Sub

#End Region

#Region "Skill Code"

    Private Sub skillNameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles skillNameTextBox.TextChanged
        _currentSkill.Name = skillNameTextBox.Text
        CheckValidSkill()
    End Sub

    Private Sub skillDescriptionTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles skillDescriptionTextBox.TextChanged
        _currentSkill.Description = skillDescriptionTextBox.Text
        CheckValidSkill()
    End Sub

    Private Sub CheckValidSkill()
        If _currentSkill.IsValid = True Then
            newSkillButton.Enabled = True
            If _currentSkill.ID <> -1 Then
                updateSkillButton.Enabled = True
            Else
                updateSkillButton.Enabled = False
            End If
        Else
            newSkillButton.Enabled = False
            updateSkillButton.Enabled = False
        End If
    End Sub

    Private Sub LoadSkills()
        If _loadingSkills = False Then
            statusToolStripLabel.Text = "Getting Skills"
            EnableSkillForm(False)
            CharClient.GetSkillsAsync(_token)
            _loadingSkills = True
        End If
    End Sub

    Private Sub CharClient_GetSkillsCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetSkillsCompletedEventArgs) Handles CharClient.GetSkillsCompleted
        If e.Result.Contains("[#]") = True Then
            MessageBox.Show(e.Result, "Failed to get Skills", MessageBoxButtons.OK, MessageBoxIcon.Error)
            _loadingSkills = False
            EnableSkillForm(True)
            Exit Sub
        End If
        skillsListView.Items.Clear()
        Dim sr As New StringReader(e.Result)
        Dim skillsXML As XElement = XElement.Load(sr)
        Dim skills = skillsXML...<skill>
        requiredSkillComboBox.Items.Clear()
        _skillTable.Clear()
        _skillValueTable.Clear()
        classSkillComboBox.Items.Clear()
        For Each aSkill In skills
            Dim item As New ListViewItem
            Dim skillName As String = aSkill.<name>.Value
            Dim skillDesc As String = aSkill.<desc>.Value
            Dim skillID As String = aSkill.@id

            item.Text = skillName
            requiredSkillComboBox.Items.Add(skillName)
            _skillTable.Add(skillID, skillName)
            _skillValueTable.Add(skillName, skillID)
            item.SubItems.Add(skillDesc)
            item.SubItems.Add(skillID.ToString)
            classSkillComboBox.Items.Add(skillName)
            skillsListView.Items.Add(item)
        Next
        statusToolStripLabel.Text = ""
        EnableSkillForm(True)
        _loadingSkills = False
    End Sub

    Private Sub newSkillButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles newSkillButton.Click
        EnableSkillForm(False)
        statusToolStripLabel.Text = "Adding New Skill"
        CharClient.AddSkillAsync(_token, _currentSkill.Name, _currentSkill.Description)
    End Sub

    Private Sub CharClient_AddSkillCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.AddSkillCompletedEventArgs) Handles CharClient.AddSkillCompleted
        EnableSkillForm(True)
        statusToolStripLabel.Text = ""
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Add Skill Failed")
            Exit Sub
        End If
        LoadSkills()
    End Sub

    Private Sub updateSkillButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles updateSkillButton.Click
        EnableSkillForm(False)
        statusToolStripLabel.Text = "Updating Skill"
        CharClient.UpdateSkillAsync(_token, _currentSkill.ID, _currentSkill.Name, _currentSkill.Description)
    End Sub

    Private Sub CharClient_UpdateSkillCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.UpdateSkillCompletedEventArgs) Handles CharClient.UpdateSkillCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Update Skill Failed")
        End If
        EnableSkillForm(True)
        statusToolStripLabel.Text = ""
        LoadSkills()
    End Sub

    Private Sub DeleteSkillToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteSkillToolStripMenuItem.Click
        Dim id As String = skillsListView.SelectedItems(0).SubItems(2).Text
        Dim skillID As Integer
        If Integer.TryParse(id, skillID) = False Then
            MessageBox.Show("Skill ID " + id + " is invalid", "Failed to delete skill", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        EnableSkillForm(False)
        CharClient.DeleteSkillAsync(_token, skillID)
    End Sub

    Private Sub CharClient_DeleteSkillCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.DeleteSkillCompletedEventArgs) Handles CharClient.DeleteSkillCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Delete Skill Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
        EnableSkillForm(True)
        LoadSkills()
    End Sub

    Private Sub skillsListView_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles skillsListView.SelectedIndexChanged
        If skillsListView.SelectedItems.Count > 0 Then
            Dim item As ListViewItem = skillsListView.SelectedItems(0)
            Dim skillID As Integer
            If Integer.TryParse(item.SubItems(2).Text, skillID) = False Then
                MessageBox.Show("Skill ID " + item.Text + " Is not a valid number", "Error Selecting Race", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If
            _currentSkill.ID = skillID
            _currentSkill.Name = item.Text
            _currentSkill.Description = item.SubItems(1).Text
            RefreshSkillDetails()
        End If
    End Sub

    Private Sub skillsContextMenuStrip_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles skillsContextMenuStrip.Opening
        If skillsListView.SelectedItems.Count = 0 Then
            e.Cancel = True
        Else
            DeleteSkillToolStripMenuItem.Text = "Delete " + skillsListView.SelectedItems(0).Text
        End If
    End Sub

    Private Sub RefreshSkillDetails()
        skillNameTextBox.Text = _currentSkill.Name
        skillDescriptionTextBox.Text = _currentSkill.Description
        CheckValidSkill()
    End Sub

    Private Sub EnableSkillForm(ByVal enabled As Boolean)
        skillsListView.Enabled = enabled
        newSkillButton.Enabled = enabled
        updateSkillButton.Enabled = enabled
        If enabled = True Then
            CheckValidSkill()
        End If
    End Sub

#End Region

#Region "Item Code"

    Private Sub LoadItems()
        If _loadingItems = False Then
            statusToolStripLabel.Text = "Getting Items"
            EnableItemForm(False)
            CharClient.GetItemsAsync(_token)
            _loadingItems = True
        End If

    End Sub

    Private Sub LoadItemTypes()
        If _loadingItemTypes = False Then
            statusToolStripLabel.Text = "Getting Item Types"
            EnableItemForm(False)
            CharClient.GetItemTypesAsync(_token)
            _loadingItemTypes = True
        End If
    End Sub

    Private Sub CharClient_GetItemsCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetItemsCompletedEventArgs) Handles CharClient.GetItemsCompleted
        itemsListView.Items.Clear()
        Dim sr As New StringReader(e.Result)
        Dim itemsXML As XElement = XElement.Load(sr)
        Dim items = itemsXML...<item>
        _itemsTable.Clear()
        _itemsValueTable.Clear()
        chargesItemComboBox.Items.Clear()
        classInitialItemsComboBox.Items.Clear()
        For Each anItem In items
            Dim item As New ListViewItem
            item.Text = anItem.@id
            _itemsTable.Add(item.Text, anItem.<name>.Value)
            _itemsValueTable.Add(anItem.<name>.Value, item.Text)
            chargesItemComboBox.Items.Add(anItem.<name>.Value)
            item.SubItems.Add(anItem.<name>.Value)
            itemsListView.Items.Add(item)
            classInitialItemsComboBox.Items.Add(anItem.<name>.Value)
        Next
        statusToolStripLabel.Text = ""
        EnableItemForm(True)
        _loadingItems = False
    End Sub

    Private Sub CharClient_GetItemTypesCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetItemTypesCompletedEventArgs) Handles CharClient.GetItemTypesCompleted
        itemTypeComboBox.Items.Clear()
        Dim sr As New StringReader(e.Result)
        Dim itemTypesXML As XElement = XElement.Load(sr)
        Dim itemTypes = itemTypesXML...<itemType>
        _itemTypeHashTable.Clear()
        _itemTypeValueHashTable.Clear()
        For Each anItemType In itemTypes
            Dim itemTypeName As String = anItemType.<name>.Value
            itemTypeComboBox.Items.Add(itemTypeName)
            _itemTypeHashTable.Add(anItemType.@id, itemTypeName)
            _itemTypeValueHashTable.Add(itemTypeName, anItemType.@id)
        Next
        statusToolStripLabel.Text = ""
        EnableItemForm(True)
        _loadingItemTypes = False
    End Sub

    Private Sub CheckValidItem()
        If _currentItem.IsValid = True Then
            newItemButton.Enabled = True
            If _currentItem.ID <> -1 Then
                updateItemButton.Enabled = True
            Else
                updateItemButton.Enabled = False
            End If
        Else
            newItemButton.Enabled = False
            updateItemButton.Enabled = False
        End If
    End Sub

    Private Sub itemNameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemNameTextBox.TextChanged
        _currentItem.Name = itemNameTextBox.Text
        CheckValidItem()
    End Sub

    Private Sub itemDescriptionTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemDescriptionTextBox.TextChanged
        _currentItem.Description = itemDescriptionTextBox.Text
        CheckValidItem()
    End Sub

    Private Sub itemIconComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemIconComboBox.SelectedIndexChanged
        _currentItem.IconImageName = itemIconComboBox.Text
        If _currentItem.IconImageName = "" Then
            itemIconPictureBox.Image = Nothing
        Else
            itemIconPictureBox.Load("./media/" + _currentItem.IconImageName)
        End If
    End Sub

    Private Sub itemImageComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemImageComboBox.SelectedIndexChanged
        _currentItem.DescriptiveImageName = itemImageComboBox.Text
        If _currentItem.DescriptiveImageName = "" Then
            itemPictureBox.Image = Nothing
        Else
            itemPictureBox.Load("./media/" + _currentItem.DescriptiveImageName)
        End If
    End Sub

    Private Sub itemDamageDiceButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemDamageDiceButton.Click
        Dim diceDialog As New TyranntEngine.dlgDiceForumla
        diceDialog.Dice = _currentItem.DamageDice
        diceDialog.ShowDialog()
        _currentItem.DamageDice = diceDialog.Dice
        diceDialog = Nothing
        RefreshItemDetails()
    End Sub

    Private Sub itemHealingDiceButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemHealingDiceButton.Click
        Dim diceDialog As New TyranntEngine.dlgDiceForumla
        diceDialog.Dice = _currentItem.HealDice
        diceDialog.ShowDialog()
        _currentItem.HealDice = diceDialog.Dice
        diceDialog = Nothing
        RefreshItemDetails()
    End Sub

    Private Sub itemDamageDiceTextBox_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles itemDamageDiceTextBox.LostFocus
        _currentItem.DamageDice.FromString = itemDamageDiceTextBox.Text
        RefreshItemDetails()
    End Sub

    Private Sub itemHealingDiceTextBox_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles itemHealingDiceTextBox.LostFocus
        _currentItem.HealDice.FromString = itemHealingDiceTextBox.Text
        RefreshItemDetails()
    End Sub

    Private Sub itemTypeComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemTypeComboBox.SelectedIndexChanged
        Dim itemTypeID As Integer
        If Integer.TryParse(CStr(_itemTypeValueHashTable(itemTypeComboBox.Text)), itemTypeID) = True Then
            _currentItem.ItemTypeID = itemTypeID
        End If
        RefreshItemDetails()
    End Sub

    Private Sub requiredSkillComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles requiredSkillComboBox.SelectedIndexChanged
        Dim skillID As Integer
        If Integer.TryParse(CStr(_skillValueTable(requiredSkillComboBox.Text)), skillID) = True Then
            _currentItem.RequiredSkillID = skillID
        End If
        RefreshItemDetails()
    End Sub

    Private Sub chargesItemComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chargesItemComboBox.SelectedIndexChanged
        Dim itemID As Integer
        If Integer.TryParse(CStr(_itemsValueTable(chargesItemComboBox.Text)), itemID) = True Then
            _currentItem.ChargesItemID = itemID
        End If
        RefreshItemDetails()
    End Sub

    Private Sub itemKeyNumberNumericBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemKeyNumberNumericBox.ValueChanged
        _currentItem.KeyNumber = CInt(itemKeyNumberNumericBox.Value)
        CheckValidItem()
    End Sub

    Private Sub numChargesNumbericBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles numChargesNumbericBox.ValueChanged
        _currentItem.NumberOfCharges = CInt(numChargesNumbericBox.Value)
        CheckValidItem()
    End Sub

    Private Sub itemDefenceValueNumberBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemDefenceValueNumberBox.ValueChanged
        _currentItem.DefenceValue = CInt(itemDefenceValueNumberBox.Value)
        CheckValidItem()
    End Sub

    Private Sub newItemButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles newItemButton.Click
        statusToolStripLabel.Text = "Adding Item"
        EnableItemForm(False)
        CharClient.AddItemAsync(_token, _currentItem.ToXElement.ToString)
    End Sub

    Private Sub CharClient_AddItemCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.AddItemCompletedEventArgs) Handles CharClient.AddItemCompleted
        statusToolStripLabel.Text = ""
        EnableItemForm(True)
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Add Item Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        LoadItems()
    End Sub

    Private Sub updateItemButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles updateItemButton.Click
        EnableItemForm(False)
        statusToolStripLabel.Text = "Updating Item"
        CharClient.UpdateItemAsync(_token, _currentItem.ToXElement.ToString)
    End Sub

    Private Sub CharClient_UpdateItemCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.UpdateItemCompletedEventArgs) Handles CharClient.UpdateItemCompleted
        If e.Result <> "" Then
            EnableItemForm(True)
            MessageBox.Show(e.Result, "Add Item Failed")
            Exit Sub
        End If
        EnableItemForm(True)
        statusToolStripLabel.Text = ""
        LoadItems()
    End Sub

    Private Sub DeleteItemToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteItemToolStripMenuItem.Click
        Dim id As String = itemsListView.SelectedItems(0).Text
        Dim itemID As Integer
        If Integer.TryParse(id, itemID) = False Then
            MessageBox.Show("Item ID " + id + " is invalid", "Failed to delete Item", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        EnableItemForm(False)
        statusToolStripLabel.Text = "Deleting Item"
        CharClient.DeleteItemAsync(_token, itemID)
    End Sub

    Private Sub CharClient_DeleteItemCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.DeleteItemCompletedEventArgs) Handles CharClient.DeleteItemCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Delete Item Failed")
            EnableItemForm(True)
            Exit Sub
        End If
        EnableItemForm(True)
        statusToolStripLabel.Text = ""
        LoadItems()
    End Sub

    Private Sub RefreshItemDetails()
        itemNameTextBox.Text = _currentItem.Name
        itemDescriptionTextBox.Text = _currentItem.Description
        itemTypeComboBox.Text = CStr(_itemTypeHashTable(_currentItem.ItemTypeID.ToString))
        itemIconComboBox.Text = _currentItem.IconImageName
        itemImageComboBox.Text = _currentItem.DescriptiveImageName
        requiredSkillComboBox.Text = CStr(_skillTable(_currentItem.RequiredSkillID.ToString))
        itemDamageDiceTextBox.Text = _currentItem.DamageDice.ToString
        itemHealingDiceTextBox.Text = _currentItem.HealDice.ToString
        itemKeyNumberNumericBox.Value = _currentItem.KeyNumber
        itemDefenceValueNumberBox.Value = _currentItem.DefenceValue
        numChargesNumbericBox.Value = _currentItem.NumberOfCharges
        chargesItemComboBox.Text = CStr(_itemsTable(_currentItem.ChargesItemID.ToString))
        CheckValidItem()
    End Sub

    Private Sub itemsContextMenuStrip_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles itemsContextMenuStrip.Opening
        If itemsListView.SelectedItems.Count = 0 Then
            e.Cancel = True
        Else
            DeleteItemToolStripMenuItem.Text = "Delete " + itemsListView.SelectedItems(0).SubItems(1).Text
        End If
    End Sub

    Private Sub itemsListView_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemsListView.SelectedIndexChanged
        If itemsListView.SelectedItems.Count > 0 Then
            Dim item As ListViewItem = itemsListView.SelectedItems(0)
            Dim itemID As Integer
            If Integer.TryParse(item.Text, itemID) = False Then
                MessageBox.Show("Item ID " + item.Text + " Is not a valid number", "Error Getting Item", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If
            EnableItemForm(False)
            statusToolStripLabel.Text = "Getting Item " + item.SubItems(0).Text + " ..."
            CharClient.GetItemAsync(_token, itemID)
        End If
    End Sub

    Private Sub CharClient_GetItemCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetItemCompletedEventArgs) Handles CharClient.GetItemCompleted
        statusToolStripLabel.Text = ""
        If e.Result.Contains("[#]") = True Then
            MessageBox.Show(e.Result, "Failed to get Item", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        _currentItem.LoadXML(e.Result)
        EnableItemForm(True)
        RefreshItemDetails()
    End Sub

    Private Sub EnableItemForm(ByVal enabled As Boolean)
        'itemsListView.Enabled = enabled
        newItemButton.Enabled = enabled
        updateItemButton.Enabled = enabled
        If enabled = True Then
            CheckValidItem()
        End If
    End Sub

#End Region

#Region "Class Code"

    Private Sub LoadClasses()
        If _loadingClasses = False Then
            statusToolStripLabel.Text = "Getting Classes"
            EnableClassForm(False)
            _loadingSkills = True
            CharClient.GetClassesAsync(_token)
        End If
    End Sub

    Private Sub CharClient_GetClassesCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetClassesCompletedEventArgs) Handles CharClient.GetClassesCompleted
        If e.Result.Contains("[#]") = True Then
            MessageBox.Show(e.Result, "Failed to get Classes", MessageBoxButtons.OK, MessageBoxIcon.Error)
            _loadingClasses = False
            EnableClassForm(True)
            Exit Sub
        End If
        classesListView.Items.Clear()
        guildInitialClassComboBox.Items.Clear()
        If e.Result <> "" Then
            Dim sr As New StringReader(e.Result)
            Dim classesXML As XElement = XElement.Load(sr)
            Dim classes = classesXML...<class>
            _classTable.Clear()
            _classValueTable.Clear()
            For Each aClass In classes
                Dim item As New ListViewItem
                Dim className As String = aClass.<name>.Value
                Dim classDesc As String = aClass.<desc>.Value
                Dim classID As String = aClass.@id

                item.Text = classID
                _classTable.Add(classID, className)
                _classValueTable.Add(className, classID)
                item.SubItems.Add(className)
                item.SubItems.Add(classDesc)
                classesListView.Items.Add(item)
                guildInitialClassComboBox.Items.Add(className)
            Next
        End If
        statusToolStripLabel.Text = ""
        EnableClassForm(True)
        _loadingClasses = False
    End Sub

    Private Sub classNameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles classNameTextBox.TextChanged
        _currentClass.Name = classNameTextBox.Text
        CheckValidClass()
    End Sub

    Private Sub classDescriptionTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles classDescriptionTextBox.TextChanged
        _currentClass.Description = classDescriptionTextBox.Text
        CheckValidClass()
    End Sub

    Private Sub classMinStrNumberBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles classMinStrNumberBox.ValueChanged
        _currentClass.MinimumStrength = CInt(classMinStrNumberBox.Value)
        CheckValidClass()
    End Sub

    Private Sub classMinDexNumberBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles classMinDexNumberBox.ValueChanged
        _currentClass.MinimumDexterity = CInt(classMinDexNumberBox.Value)
        CheckValidClass()
    End Sub

    Private Sub classMinIntNumberBox_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles classMinIntNumberBox.ValueChanged
        _currentClass.MinimumIntelligence = CInt(classMinIntNumberBox.Value)
        CheckValidClass()
    End Sub

    Private Sub addClassSkillButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addClassSkillButton.Click
        Dim skillID As Integer
        Dim skill As String = classSkillComboBox.Text
        If skill <> "" Then
            If Integer.TryParse(CStr(_skillValueTable(skill)), skillID) = True Then
                _currentClass.Skills.Add(skillID)
            End If
        End If
        RefreshClassDetails()
    End Sub

    Private Sub classAddItemButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles classAddItemButton.Click
        Dim itemID As Integer
        Dim item As String = classInitialItemsComboBox.Text
        If item <> "" Then
            If Integer.TryParse(CStr(_itemsValueTable(item)), itemID) = True Then
                _currentClass.Items.Add(itemID)
            End If
        End If
        RefreshClassDetails()
    End Sub

    Private Sub newClassButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles newClassButton.Click
        EnableClassForm(False)
        CharClient.AddClassAsync(_token, _currentClass.ToXElement.ToString)
    End Sub

    Private Sub CharClient_AddClassCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.AddClassCompletedEventArgs) Handles CharClient.AddClassCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Add Class Failed")
        End If
        statusToolStripLabel.Text = ""
        EnableClassForm(True)
        LoadClasses()
    End Sub

    Private Sub updateClassButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles updateClassButton.Click
        EnableClassForm(False)
        CharClient.UpdateClassAsync(_token, _currentClass.ToXElement.ToString)
    End Sub

    Private Sub CharClient_UpdateClassCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.UpdateClassCompletedEventArgs) Handles CharClient.UpdateClassCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Update Class Failed")
        End If
        statusToolStripLabel.Text = ""
        EnableClassForm(True)
        LoadClasses()
    End Sub

    Private Sub DeleteClassToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteClassToolStripMenuItem.Click
        Dim id As String = classesListView.SelectedItems(0).Text
        Dim classID As Integer
        If Integer.TryParse(id, classID) = False Then
            MessageBox.Show("Class ID " + id + " is invalid", "Failed to delete class", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
        EnableClassForm(False)
        statusToolStripLabel.Text = "Deleting Class"
        CharClient.DeleteClassAsync(_token, classID)
    End Sub

    Private Sub CharClient_DeleteClassCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.DeleteClassCompletedEventArgs) Handles CharClient.DeleteClassCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Delete Class Failed")
        End If
        statusToolStripLabel.Text = ""
        EnableClassForm(True)
        LoadClasses()
    End Sub

    Private Sub clearClassButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles clearClassButton.Click
        _currentClass = New TyranntEngine.CharacterClass
        RefreshClassDetails()
    End Sub

    Private Sub classesContextMenuStrip_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles classesContextMenuStrip.Opening
        If classesListView.SelectedItems.Count = 0 Then
            e.Cancel = True
        Else
            DeleteClassToolStripMenuItem.Text = "Delete " + classesListView.SelectedItems(0).SubItems(1).Text
        End If
    End Sub

    Private Sub classesListView_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles classesListView.SelectedIndexChanged
        If classesListView.SelectedItems.Count > 0 Then
            Dim item As ListViewItem = classesListView.SelectedItems(0)
            Dim classID As Integer
            If Integer.TryParse(item.Text, classID) = False Then
                MessageBox.Show("Class ID " + item.Text + " Is not a valid number", "Error Selecting Class", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If
            EnableClassForm(False)
            CharClient.GetClassAsync(_token, classID)
        End If
    End Sub

    Private Sub CharClient_GetClassCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetClassCompletedEventArgs) Handles CharClient.GetClassCompleted
        If e.Result.Contains("[#]") = True Then
            MessageBox.Show(e.Result, "Failed to get Class", MessageBoxButtons.OK, MessageBoxIcon.Error)
            EnableClassForm(True)
            Exit Sub
        End If
        _currentClass.LoadXML(e.Result)
        EnableClassForm(True)
        RefreshClassDetails()
    End Sub

    Private Sub RemoveSkillToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveSkillToolStripMenuItem.Click
        _currentClass.Skills.Remove(CInt(_skillValueTable(classInitialSkillsListView.SelectedItems(0).Text)))
        RefreshClassDetails()
    End Sub

    Private Sub classInitialSkillsContextMenuStrip_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles classInitialSkillsContextMenuStrip.Opening
        If classInitialSkillsListView.SelectedItems.Count = 0 Then
            e.Cancel = True
        Else
            RemoveSkillToolStripMenuItem.Text = "Remove " + classInitialSkillsListView.SelectedItems(0).Text
        End If
    End Sub

    Private Sub RemoveItemToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveItemToolStripMenuItem.Click
        _currentClass.Items.Remove(CInt(_itemsValueTable(classInitialItemsListView.SelectedItems(0).Text)))
        RefreshClassDetails()
    End Sub

    Private Sub classInitialItemsContextMenuStrip_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles classInitialItemsContextMenuStrip.Opening
        If classInitialItemsListView.SelectedItems.Count = 0 Then
            e.Cancel = True
        Else
            RemoveItemToolStripMenuItem.Text = "Remove " + classInitialItemsListView.SelectedItems(0).Text
        End If
    End Sub

    Private Sub RefreshClassDetails()
        classNameTextBox.Text = _currentClass.Name
        classDescriptionTextBox.Text = _currentClass.Description
        classMinStrNumberBox.Value = _currentClass.MinimumStrength
        classMinDexNumberBox.Value = _currentClass.MinimumDexterity
        classMinIntNumberBox.Value = _currentClass.MinimumIntelligence
        classInitialSkillsListView.Items.Clear()
        classInitialItemsListView.Items.Clear()
        For Each id As Integer In _currentClass.Skills
            Dim item As String = CStr(_skillTable(id.ToString))
            classInitialSkillsListView.Items.Add(item)
        Next
        For Each id As Integer In _currentClass.Items
            Dim item As String = CStr(_itemsTable(id.ToString))
            classInitialItemsListView.Items.Add(item)
        Next
        CheckValidClass()
    End Sub

    Private Sub EnableClassForm(ByVal enabled As Boolean)
        'classesListView.Enabled = enabled
        newClassButton.Enabled = enabled
        updateClassButton.Enabled = enabled
        If enabled = True Then
            CheckValidClass()
        End If
    End Sub

    Private Sub CheckValidClass()
        If _currentClass.IsValid = True Then
            newClassButton.Enabled = True
            If _currentClass.ID <> -1 Then
                updateClassButton.Enabled = True
            Else
                updateClassButton.Enabled = False
            End If
        Else
            newClassButton.Enabled = False
            updateClassButton.Enabled = False
        End If
    End Sub

#End Region

#Region "Guild Code"

    Private Sub LoadGuilds()
        If _loadingGuilds = False Then
            _loadingGuilds = True
            EnableGuildForm(False)
            CharClient.GetGuildsAsync(_token)
        End If
    End Sub

    Private Sub CharClient_GetGuildsCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetGuildsCompletedEventArgs) Handles CharClient.GetGuildsCompleted
        If e.Result.Contains("[#]") = True Then
            MessageBox.Show(e.Result, "Failed to get Guilds", MessageBoxButtons.OK, MessageBoxIcon.Error)
            _loadingGuilds = False
            EnableGuildForm(True)
            Exit Sub
        End If
        guildsListView.Items.Clear()
        If e.Result <> "" Then
            Dim sr As New StringReader(e.Result)
            Dim guildsXML As XElement = XElement.Load(sr)
            Dim guilds = guildsXML...<guild>
            For Each aGuild In guilds
                Dim item As New ListViewItem
                Dim guildName As String = aGuild.<name>.Value
                Dim guildID As String = aGuild.@id

                item.Text = guildID
                item.SubItems.Add(guildName)
                guildsListView.Items.Add(item)
            Next
        End If
        statusToolStripLabel.Text = ""
        EnableGuildForm(True)
        _loadingGuilds = False
    End Sub

    Private Sub guildNameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles guildNameTextBox.TextChanged
        _currentGuild.Name = guildNameTextBox.Text
        CheckValidGuild()
    End Sub

    Private Sub guildDescriptionTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles guildDescriptionTextBox.TextChanged
        _currentGuild.Description = guildDescriptionTextBox.Text
        CheckValidGuild()
    End Sub

    Private Sub guildInitialClassComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles guildInitialClassComboBox.SelectedIndexChanged
        _currentGuild.InitialClassID = Integer.Parse(CStr(_classValueTable(guildInitialClassComboBox.Text)))
        CheckValidGuild()
    End Sub

    Private Sub newGuildButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles newGuildButton.Click
        EnableGuildForm(False)
        CharClient.AddGuildAsync(_token, _currentGuild.ToXElement.ToString)
    End Sub

    Private Sub CharClient_AddGuildCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.AddGuildCompletedEventArgs) Handles CharClient.AddGuildCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Add Guild Failed")
        End If
        statusToolStripLabel.Text = ""
        EnableGuildForm(True)
        LoadGuilds()
    End Sub

    Private Sub CharClient_GetGuildCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.GetGuildCompletedEventArgs) Handles CharClient.GetGuildCompleted
        If e.Result.Contains("[#]") = True Then
            MessageBox.Show(e.Result, "Failed to get Guild", MessageBoxButtons.OK, MessageBoxIcon.Error)
            EnableGuildForm(True)
            Exit Sub
        End If
        _currentGuild.LoadXML(e.Result)
        EnableGuildForm(True)
        RefreshGuildDetails()
    End Sub

    Private Sub updateGuildButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles updateGuildButton.Click
        EnableGuildForm(False)
        CharClient.UpdateGuildAsync(_token, _currentGuild.ToXElement.ToString)
    End Sub

    Private Sub CharClient_UpdateGuildCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.UpdateGuildCompletedEventArgs) Handles CharClient.UpdateGuildCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Update Guild Failed")
        End If
        statusToolStripLabel.Text = ""
        EnableGuildForm(True)
        LoadGuilds()
    End Sub

    Private Sub guildsContextMenuStrip_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles guildsContextMenuStrip.Opening
        If guildsListView.SelectedItems.Count = 0 Then
            e.Cancel = True
        Else
            DeleteGuildToolStripMenuItem.Text = "Delete " + guildsListView.SelectedItems(0).SubItems(1).Text
        End If
    End Sub

    Private Sub DeleteGuildToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteGuildToolStripMenuItem.Click
        EnableGuildForm(False)
        CharClient.DeleteGuildAsync(_token, _currentGuild.ID)
    End Sub

    Private Sub CharClient_DeleteGuildCompleted(ByVal sender As Object, ByVal e As TyranntOnlineCharacterService.DeleteGuildCompletedEventArgs) Handles CharClient.DeleteGuildCompleted
        If e.Result <> "" Then
            MessageBox.Show(e.Result, "Delete Guild Failed")
        End If
        statusToolStripLabel.Text = ""
        EnableGuildForm(True)
        LoadGuilds()
    End Sub

    Private Sub guildsListView_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles guildsListView.SelectedIndexChanged
        If guildsListView.SelectedItems.Count > 0 Then
            Dim item As ListViewItem = guildsListView.SelectedItems(0)
            Dim guildID As Integer
            If Integer.TryParse(item.Text, guildID) = False Then
                MessageBox.Show("Guild ID " + item.Text + " Is not a valid number", "Error Selecting Guild", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If
            EnableGuildForm(False)
            CharClient.GetGuildAsync(_token, guildID)
        End If
    End Sub

    Private Sub EnableGuildForm(ByVal enabled As Boolean)
        newGuildButton.Enabled = enabled
        updateGuildButton.Enabled = enabled
        If enabled = True Then
            CheckValidGuild()
        End If
    End Sub

    Private Sub CheckValidGuild()
        If _currentGuild.IsValid = True Then
            newGuildButton.Enabled = True
            If _currentGuild.ID <> -1 Then
                updateGuildButton.Enabled = True
            Else
                updateGuildButton.Enabled = False
            End If
        Else
            newGuildButton.Enabled = False
            updateGuildButton.Enabled = False
        End If
    End Sub

    Private Sub RefreshGuildDetails()
        guildNameTextBox.Text = _currentGuild.Name
        guildDescriptionTextBox.Text = _currentGuild.Description
        guildInitialClassComboBox.Text = CStr(_classTable(_currentGuild.InitialClassID.ToString))
        CheckValidGuild()
    End Sub

#End Region

End Class